Skip to content

feat: add campaign mode for multi-stage plugin modernization#1707

Open
Fikri-20 wants to merge 8 commits intojenkins-infra:mainfrom
Fikri-20:feat/campaign-mode
Open

feat: add campaign mode for multi-stage plugin modernization#1707
Fikri-20 wants to merge 8 commits intojenkins-infra:mainfrom
Fikri-20:feat/campaign-mode

Conversation

@Fikri-20
Copy link
Copy Markdown
Contributor

@Fikri-20 Fikri-20 commented Apr 15, 2026

The tool today runs one recipe, one invocation. If you want to modernize a plugin properly - Dependabot, security scan, parent POM upgrade - that's three separate runs, three separate outputs, no connection between them.

Campaign mode fixes that. One YAML file, one run, one report.

Adds a campaign subcommand. It reads a YAML file that defines plugin sources, an ordered list of recipe stages, and execution settings. Each stage runs on the local workspace left by the previous one - no re-clone between stages. Always runs in dry-run mode: no commits, forks, or PRs are created.

Plugin sources can be combined: explicit names, a file, local paths, or the top N by install count. Filters on health score, install count, and deprecation status narrow the set before execution begins.

Testing done

Ran against permissive-script-security (health score 71, no .github/ dir):
photo_2026-04-15_14-59-58

image image

Submitter checklist

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests - that demonstrates feature works or fixes the issue

@Fikri-20 Fikri-20 requested a review from jonesbusy as a code owner April 15, 2026 12:55
…erters

Move recipe name resolution and local plugin path resolution out of
the picocli converters into standalone core utilities so they can be
reused by campaign mode without depending on the CLI layer.
Add Jackson-mapped classes for campaign input (definition, stages,
plugin sources, filters, execution settings, output config) and for
the structured JSON report (campaign, per-plugin, per-stage).
Validates that at least one plugin source is declared, stages are
non-empty, all recipe names resolve, and topPlugins is positive.
Resolves plugins from names, file, localPaths, and topPlugins sources.
Sources are combined and deduplicated. Filters on install count, health
score, deprecation, and adoption status are applied before returning
the final list. Throws if no plugins survive the filters.
CampaignService orchestrates per-plugin stage execution using a
fixed thread pool. Each stage reuses the local workspace from the
previous one. Stops on first failure per plugin unless
continueOnFailure is set. Writes the JSON report at the end.

DefaultCampaignModernizerRunner delegates each stage to the existing
PluginModernizer engine.
Register CampaignCommand as a subcommand in Main. Bind
CampaignModernizerRunner to DefaultCampaignModernizerRunner in
GuiceModule. Add testCampaignOnLocalPlugin integration test.
@Fikri-20 Fikri-20 force-pushed the feat/campaign-mode branch from 1875981 to 6754e9a Compare April 15, 2026 13:06
@Fikri-20
Copy link
Copy Markdown
Contributor Author

@jonesbusy
Hey, could you please review this PR when you have some time?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant